
using System;
using System.Collections.Generic;

namespace TSP
{

public class AdjacencyMatrixGraph : Graph
{

protected double?[,] am;

public AdjacencyMatrixGraph(bool directed, int verticesCount) : base(directed,verticesCount)
{
am = new double?[verticesCount,verticesCount];
}

public AdjacencyMatrixGraph(IGraph g) : this(g.Directed,g.VerticesCount)
{
Construct(g);
}

public override IGraph Clone()
{
return new AdjacencyMatrixGraph(this);
}

public override IGraph IsolatedVerticesGraph()
{
return new AdjacencyMatrixGraph(directed,VerticesCount);
}

public override bool AddEdge(int from, int to, double weight)
{
if ( am[from,to]!=null ) return false;
am[from,to]=weight;
++vertices[from].outDegree;
++vertices[to].inDegree;
if ( !directed )
    {
    am[to,from]=weight;
    ++vertices[to].outDegree;
    ++vertices[from].inDegree;
    }
return true;
}

public override bool DelEdge(int from, int to)
{
if ( am[from,to]==null ) return false;
am[from,to]=null;
--vertices[from].outDegree;
--vertices[to].inDegree;
if ( !directed )
    {
    am[to,from]=null;
    --vertices[to].outDegree;
    --vertices[from].inDegree;
    }
return true;
}

public override void AddVertex()
{
Vertex[] v2 = new Vertex[VerticesCount+1];
double?[,] am2 = new double?[VerticesCount+1,VerticesCount+1];
for ( int i=0 ; i<VerticesCount ; ++i )
    {
    v2[i]=vertices[i];
    for ( int j=0 ; j<VerticesCount ; ++j )
        am2[i,j]=am[i,j];
    }
vertices=v2;
am=am2;
}

public override void DelVertex(int nr)
{
if ( VerticesCount==1 || nr<0 || nr>=VerticesCount ) throw new IndexOutOfRangeException();
Vertex[] v2 = new Vertex[VerticesCount-1];
double?[,] am2 = new double?[VerticesCount-1,VerticesCount-1];
int ii,jj;
for ( int i=0 ; i<VerticesCount ; ++i )
    {
    if ( i==nr ) continue;
    ii= (i<nr) ? i : i-1 ; 
    v2[ii]=vertices[i];
    for ( int j=0 ; j<VerticesCount ; ++j )
        {
        if ( j==nr ) continue;
        jj= (j<nr) ? j : j-1 ; 
        am2[ii,jj]=am[i,j];
        }
    }
vertices=v2;
am=am2;
}

public override IEnumerable<Edge> OutEdges(int from)
{
for ( int to=0 ; to<VerticesCount ; ++to )
    if ( am[from,to]!=null )
        yield return new Edge(from,to,(double)am[from,to]);
}

}  //  class AdjacencyMatrixGraph

}  //  namespace ASD.Graph
